import com.fazecast.jSerialComm.SerialPort;
import com.fazecast.jSerialComm.SerialPortDataListener;
import com.fazecast.jSerialComm.SerialPortEvent;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SerialPortTool extends JFrame {
    private SerialPort serialPort;
    private boolean isConnected = false;

    private JComboBox<String> comboBoxPorts;
    private JButton buttonOpenClose;
    private JTextArea textAreaReceived;
    private JTextField textFieldSend;
    private JButton buttonSend;

    public SerialPortTool() {
        setTitle("串口调试工具");
        setSize(500, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initUI();
    }

    private void initUI() {
        JPanel panel = new JPanel(new BorderLayout());

        // 串口选择
        JPanel topPanel = new JPanel();
        comboBoxPorts = new JComboBox<>();
        refreshPorts();
        topPanel.add(new JLabel("选择串口:"));
        topPanel.add(comboBoxPorts);

        buttonOpenClose = new JButton("打开串口");
        buttonOpenClose.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (isConnected) {
                    closePort();
                } else {
                    openPort();
                }
            }
        });
        topPanel.add(buttonOpenClose);
        panel.add(topPanel, BorderLayout.NORTH);

        // 接收数据显示
        textAreaReceived = new JTextArea();
        textAreaReceived.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textAreaReceived);
        panel.add(scrollPane, BorderLayout.CENTER);

        // 发送数据
        JPanel bottomPanel = new JPanel(new BorderLayout());
        textFieldSend = new JTextField();
        bottomPanel.add(textFieldSend, BorderLayout.CENTER);

        buttonSend = new JButton("发送");
        buttonSend.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendData();
            }
        });
        bottomPanel.add(buttonSend, BorderLayout.EAST);
        panel.add(bottomPanel, BorderLayout.SOUTH);

        add(panel);
    }

    private void refreshPorts() {
        comboBoxPorts.removeAllItems();
        SerialPort[] ports = SerialPort.getCommPorts();
        for (SerialPort port : ports) {
            comboBoxPorts.addItem(port.getSystemPortName());
        }
    }

    private void openPort() {
        if (comboBoxPorts.getSelectedItem() == null) {
            JOptionPane.showMessageDialog(this, "请选择一个串口！");
            return;
        }

        String portName = comboBoxPorts.getSelectedItem().toString();
        serialPort = SerialPort.getCommPort(portName);
        serialPort.setBaudRate(9600);
        serialPort.setNumDataBits(8);
        serialPort.setNumStopBits(1);
        serialPort.setParity(SerialPort.NO_PARITY);

        if (serialPort.openPort()) {
            isConnected = true;
            buttonOpenClose.setText("关闭串口");
            JOptionPane.showMessageDialog(this, "串口已打开！");

            serialPort.addDataListener(new SerialPortDataListener() {
                @Override
                public int getListeningEvents() {
                    return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
                }

                @Override
                public void serialEvent(SerialPortEvent event) {
                    if (event.getEventType() == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
                        byte[] buffer = new byte[serialPort.bytesAvailable()];
                        serialPort.readBytes(buffer, buffer.length);
                        String data = new String(buffer);
                        SwingUtilities.invokeLater(() -> textAreaReceived.append("接收: " + data + "\n"));
                    }
                }
            });
        } else {
            JOptionPane.showMessageDialog(this, "打开串口失败！");
        }
    }

    private void closePort() {
        if (serialPort != null && serialPort.closePort()) {
            isConnected = false;
            buttonOpenClose.setText("打开串口");
            JOptionPane.showMessageDialog(this, "串口已关闭！");
        } else {
            JOptionPane.showMessageDialog(this, "关闭串口失败！");
        }
    }

    private void sendData() {
        if (isConnected) {
            String data = textFieldSend.getText();
            byte[] buffer = data.getBytes();
            serialPort.writeBytes(buffer, buffer.length);
            textAreaReceived.append("发送: " + data + "\n");
            textFieldSend.setText("");
        } else {
            JOptionPane.showMessageDialog(this, "请先打开串口！");
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SerialPortTool tool = new SerialPortTool();
            tool.setVisible(true);
        });
    }
}